package com.sunrise.crm.servico;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

import javax.annotation.Resource;

import lombok.Getter;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sunrise.configuracoes.repositorio.iface.PessoaDao;
import com.sunrise.crm.repositorio.iface.CidadeDao;
import com.sunrise.crm.repositorio.iface.ContatoDao;
import com.sunrise.crm.repositorio.iface.EnderecoDao;
import com.sunrise.crm.repositorio.iface.EstadoDao;
import com.sunrise.crm.repositorio.iface.TipoPessoaDao;
import com.sunrise.generico.entidade.Cidade;
import com.sunrise.generico.entidade.Contato;
import com.sunrise.generico.entidade.Endereco;
import com.sunrise.generico.entidade.Estado;
import com.sunrise.generico.entidade.Pessoa;
import com.sunrise.generico.entidade.TipoPessoa;
import com.sunrise.generico.visao.Filtro;

@Service
@Transactional(readOnly = true)
public class ManterPessoaService {

	@Resource(name = "pessoaDaoImpl")
	@Getter
	private PessoaDao pessoaDAO;

	@Resource(name = "cidadeDaoImpl")
	@Getter
	private CidadeDao cidadeDAO;

	@Resource(name = "contatoDaoImpl")
	@Getter
	private ContatoDao contatoDAO;

	@Resource(name = "enderecoDaoImpl")
	@Getter
	private EnderecoDao enderecoDAO;

	@Resource(name = "estadoDaoImpl")
	@Getter
	private EstadoDao estadoDAO;

	@Resource(name = "tipoPessoaDaoImpl")
	@Getter
	private TipoPessoaDao tipoPessoaDAO;

	public Collection<Pessoa> buscarPorFiltros(Filtro filtro) {
		return getPessoaDAO().buscarPorFiltros(filtro);
	}

	public Cidade buscarCidadePorNome(String cidade) {
		return getCidadeDAO().buscarPorNome(cidade);
	}

	public Collection<Estado> listarEstados() {
		return getEstadoDAO().listarOrdenado();
	}

	public Collection<Cidade> carregarCidadesPorEstado(Estado estado) {
		return getCidadeDAO().listarPorEstado(estado);
	}

	public Collection<TipoPessoa> listarNaoUsuarios() {
		return getTipoPessoaDAO().listarNaoUsuarios();
	}

	@Transactional(readOnly = false)
	public void salvar(Pessoa entidade) {
		entidade.setDataCriacao(new Date());
		entidade.setContato(inserirContato(entidade.getContato()));
		entidade.setEndereco(inserirEndereco(entidade.getEndereco()));
		Collection<TipoPessoa> tipos = new ArrayList<TipoPessoa>();
		for(TipoPessoa tipo : entidade.getTiposPessoa()){
			tipos.add(getTipoPessoaDAO().getById(tipo.getId()));
		}
		entidade.setTiposPessoa(tipos);
		getPessoaDAO().inserir(entidade);
	}

	private Endereco inserirEndereco(Endereco endereco) {
		if (endereco.getBairro() != null && !endereco.getBairro().isEmpty()
				|| (endereco.getCep() != null && !endereco.getCep().isEmpty())
				|| (endereco.getCidade() != null && endereco.getCidade().getId() != null && endereco.getCidade().getId() != 0)
				|| (endereco.getComplemento() != null && !endereco.getComplemento().isEmpty())
				|| (endereco.getEndereco() != null && !endereco.getEndereco().isEmpty())) {
			getEnderecoDAO().inserir(endereco);
			return endereco;
		}
		return null;

	}

	private Contato inserirContato(Contato contato) {
		if ((contato.getCelular() != null && !contato.getCelular().isEmpty())
				|| (contato.getEmail() != null && !contato.getEmail().isEmpty())
				|| (contato.getFax() != null && !contato.getFax().isEmpty())
				|| (contato.getTelefone() != null && !contato.getTelefone().isEmpty())) {
			getContatoDAO().inserir(contato);
			return contato;
		}
		return null;

	}
	
	@Transactional(readOnly = false)
	public void remover(Pessoa entidade) {
		getPessoaDAO().remover(entidade);
	}

	public Pessoa buscarPessoaPorId(Long id) {
		Pessoa pessoa = getPessoaDAO().getById(id);
		
		Collection<TipoPessoa> tipos = new ArrayList<TipoPessoa>();
		for(TipoPessoa tipo : pessoa.getTiposPessoa()){
			tipos.add(getTipoPessoaDAO().getById(tipo.getId()));
			tipo.setPessoas(null);
		}
		pessoa.setTiposPessoa(tipos);
		return pessoa;
	}

	@Transactional(readOnly = false)
	public void alterar(Pessoa entidade) {
		salvarEndereco(entidade.getEndereco());
		
		if(entidade.getContato().getId() == null){
			getContatoDAO().inserir(entidade.getContato());
		} else{
			getContatoDAO().alterar(entidade.getContato());
		}
		
		Collection<TipoPessoa> tipos = new ArrayList<TipoPessoa>();
		for(TipoPessoa tipo : entidade.getTiposPessoa()){
			tipos.add(getTipoPessoaDAO().getById(tipo.getId()));
		}
		entidade.setTiposPessoa(tipos);
		getPessoaDAO().alterar(entidade);
	}

	private void salvarEndereco(Endereco endereco) {
		if(endereco != null && endereco.getCidade() != null && endereco.getCidade().getId() == 0){
			endereco.setCidade(null);
		}
		
		if(endereco.getId() == null){
			getEnderecoDAO().inserir(endereco);
		} else {
			getEnderecoDAO().alterar(endereco);
		}
	}

	public Collection<Pessoa> listarOrdenado(Pessoa entidade, String tipoPessoa) {
		Collection<Pessoa> pessoas = getPessoaDAO().listarOrdenadoPorTipoPessoa(tipoPessoa);
		for(Pessoa pessoa : pessoas){
			pessoa.getTiposPessoa().size();
		}
		return pessoas;
	}

	public TipoPessoa buscarTipoPessoaPorNome(String nome) {
		return getTipoPessoaDAO().buscarPorNome(nome);
	}

}